import React, {
  useState,
  useEffect,
  useContext,
  createContext,
  useReducer,
  useMemo,
  useCallback,
  useRef,
  memo,
} from 'react'
import { Button, Input } from 'antd'


/**
 * usuState
 */
function UseStateExam() {
  const [count, setCount] = useState(0)
  // console.log("组件更新");
  return (
    <div>
      <p>You clicked : {count}</p>
      <Button onClick={() => setCount(count + 1)}>count ++</Button>
    </div>
  )
}

/**
 * useEffect
 */

function UseEffectExam() {
  const [count, setCount] = useState(0)
  useEffect(() => {
    // console.log(`useEffect 执行 ${count}`)

    return () => {
      // console.log("页面卸载");
    }
  }, [count])

  return (
    <div>
      <p>You clicked : {count}</p>
      <Button onClick={() => setCount(count + 1)}>count ++</Button>
    </div>
  )
}


/**
 * useContext
 */

const CountContext = createContext()
function UseContextExam() {
  const [count, setCount] = useState(0)
  return (
    <div>
      <h2>父组件</h2>
      <p>You clicked : {count}</p>
      <Button onClick={() => setCount(count + 1)}>count ++</Button>
      <CountContext.Provider value={count}>
        <Childer1 />
      </CountContext.Provider>
    </div>
  )
}

function Childer1() {
  // CountContext 这个实例是要和父组件的是同一个实例才可以?
  let count = useContext(CountContext)
  return (
    <div>
      <h2>子组件1</h2>
      <p>子组件接受到:{count}</p>
    </div>
  )
}

/**
 * useReducer
 */
function UseReducerExam() {
  const [count, dispatch] = useReducer((state, action) => {
    switch (action) {
      case "add":
        return state + 1
      case "sub":
        return state - 1
      default:
        return state
    }
  }, 0)

  return (
    <div>
      <p>You clicked : {count}</p>
      <Button onClick={() => dispatch('add')}>count ++</Button>
      <Button onClick={() => dispatch('sub')}>count --</Button>
    </div>
  )
}





/**
 *  usememo
 */

function UseMomeExam() {
  const [itemName, setItemName] = useState("商品" + 1)
  const [itemPrice, setItemPrice] = useState(1)
  const [itemCount, setItemCount] = useState(1)
  console.log('UseMome');
  const MemeChildren = useMemo(() => UseMomeChildren(itemCount, itemPrice), [itemCount, itemPrice])
  return (
    <div>
      <span>商品名称:{itemName}</span>
      <span>商品单价:{itemPrice}</span>
      <span>商品数量:{itemCount}</span>
      <br />
      <Button onClick={() => setItemPrice(itemPrice + 1)}>单价++</Button>
      <Button onClick={() => setItemCount(itemCount + 1)}>数量++</Button>
      <Button onClick={() => setItemName(itemName + 1)}>更换商品</Button>
      {/* 商品总价 */}
      {/* <h3>商品总价: {MemeChildren}</h3> */}
      {MemeChildren}
    </div>
  )
}

function UseMomeChildren(c, p) {
  console.log('计算总价');
  return (
    <div>
      <p>当商品价格和商品数量改变时,商品总价重新计算，<br />商品名称改变时，不重新渲染</p>
      <h3>商品总价:{c * p}</h3>
    </div>
  )
}


/**
 * 
 * @returns useRef
 */

const inputStyle = {
  width: "220px"
}

function UseRefExam() {
  const inputEl = useRef(null)

  // 获取DOM input
  const onButtonClick = () => {
    // inputEl.current.value = "Hello World"
    console.log("inputEl", inputEl);
  }

  const [text, setText] = useState('hello ')
  const textRef = useRef()

  // setText触发，就将输入框的内容保存
  useEffect(() => {
    textRef.current = text
    console.log('textRef.current', textRef.current);
  })

  return (
    <div>
      <Input style={inputStyle} ref={inputEl} type="text" />
      <Button onClick={onButtonClick}>在input上的文字</Button>
      <br />
      <br />
      <Input style={inputStyle} value={text} onChange={(e) => setText(e.target.value)} />
    </div>
  )

}


/**
 * 自动以hook useCallback
 */

function useWinSize() {
  const [size, setSize] = useState({
    width: document.documentElement.clientWidth,
    height: document.documentElement.clientHeight
  })

  const onResize = useCallback(
    () => {
      setSize({
        width: document.documentElement.clientWidth,
        height: document.documentElement.clientHeight
      })
    },
    [],
  )

  useEffect(() => {
    window.addEventListener('resize', onResize)
    return () => {
      window.removeEventListener('resize', onResize)
    }
  })

  return size
}


function HookTesh() {
  const size = useWinSize()
  return (
    <div>页面的Siz:{size.width} * {size.height}</div>
  )
}


export {
  UseStateExam,
  UseEffectExam,
  UseContextExam,
  UseReducerExam,
  UseMomeExam,
  UseRefExam,
  HookTesh
}

